PREEMPT_RT 实时应用程序教程


PREEMPT_RT 实时应用程序教程

这些教程通常需要一个终端用于执行教程应用程序,至少一个额外的终端用于执行各种影响应用程序行为的压力测试,或用于监控以捕获其操作的统计信息。最好通过 SSH 远程访问执行教程的系统,以避免桌面 GUI 中断影响测量结果(非xkernel内核)。

教程包括:


CPU亲和性

在非隔离的CPU上测试

开始在CPU2上执行应用程序(非隔离)

latency -c2 -t0 -p 100 -P 99 -h

平均值为 30µs

在隔离的CPU上测试

开始在CPU1上执行应用程序(隔离)

latency -c1 -t0 -p 100 -P 99 -h

平均值为 10µs


内存锁定教程

页面错误(Page faults)会对确定性产生负面影响。内存锁定可以防止应用程序中大部分甚至全部页面错误的发生。

可以通过健康监测工具健康进程的Page faults次数

sudo sjournal_run 1h


实时线程优先级

实时应用程序会抢占其他非实时的应用程序。优先级参数设置执行工作负载的线程优先级。当此参数被省略或设置为零时,线程不是实时的。将其设置为99可确保RT执行。

使用代码设置为实时线程优先级

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sched.h>
#include <unistd.h>

// 线程函数
void* thread_func(void* arg) {
    while (1) {
        // 模拟一些工作
        sleep(1);
    }
    return NULL;
}

int main() {
    pthread_t thread;
    struct sched_param param;
    int policy = SCHED_FIFO;  // 使用 FIFO 实时调度策略
    int max_priority, min_priority;

    // 创建线程
    if (pthread_create(&thread, NULL, thread_func, NULL) != 0) {
        perror("无法创建线程");
        return 1;
    }

    // 获取 SCHED_FIFO 策略的最大和最小优先级
    max_priority = sched_get_priority_max(SCHED_FIFO);
    min_priority = sched_get_priority_min(SCHED_FIFO);

    printf("SCHED_FIFO 最大优先级: %d, 最小优先级: %d\n", max_priority, min_priority);

    // 设置线程的优先级(选择一个合适的值,如最大优先级)
    param.sched_priority = max_priority;

    // 设置线程的调度策略和优先级
    if (pthread_setschedparam(thread, policy, &param) != 0) {
        perror("无法设置线程优先级");
        return 1;
    }

    printf("线程已设置为实时优先级 (SCHED_FIFO, 优先级: %d)\n", param.sched_priority);

    // 等待线程结束
    pthread_join(thread, NULL);

    return 0;
}

使用命令行设置线程为实时线程

# 将正在运行的进程转换为实时调度策略
sudo chrt -f 99 <priority> <pid>

# 以实时调度策略启动新进程
sudo chrt -f 99 <priority> <command>

使用下面的命令查看设置是否成功

chrt -p <pid>